# -*- coding: utf-8 -*-
# Author   : ZhangQing
# Time     : 2025-08-04 23:31
# File     : code_routes.py
# Project  : codebuddy_craft
# Desc     : 代码相关接口
# backend/api/code_routes.py
from typing import Dict, List, Optional, Any
from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel, Field

from backend.core.agents.code_generator import code_generator, CodeGenerationRequest, CodeGenerationResponse
from backend.core.chains.analysis_chain import code_analysis_chain, AnalysisResult
from backend.core.chains.completion_chain import completion_chain, CompletionResult
from backend.utils.security import get_current_user_id


router = APIRouter()


class CompletionRequest(BaseModel):
    """智能补全请求"""
    file_id: str = Field(description="文件ID")
    line: int = Field(description="行号")
    column: int = Field(description="列号")
    context: Optional[str] = Field(default=None, description="上下文代码")


class AnalysisRequest(BaseModel):
    """代码分析请求"""
    project_id: str = Field(description="项目ID")
    scope: str = Field(description="@引用范围")
    prompt: str = Field(description="问题描述")


class TranslationRequest(BaseModel):
    """代码翻译请求"""
    code: str = Field(description="代码片段")
    source_language: str = Field(description="源语言")
    target_language: str = Field(description="目标语言")


class SyntaxCheckRequest(BaseModel):
    """语法检查请求"""
    code: str = Field(description="代码片段")
    language: str = Field(description="编程语言")


@router.post("/generate", response_model=Dict[str, Any])
async def generate_code(
    request: CodeGenerationRequest,
    user_id: str = Depends(get_current_user_id)
):
    """生成代码"""
    try:
        result = await code_generator.generate_code(request)
        
        return {
            "code": 200,
            "msg": "成功",
            "data": {
                "code_block": result.code_block,
                "explanation": result.explanation,
                "model_used": result.model_used,
                "suggestions": result.suggestions
            }
        }
    
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail={
                "code": 50001,
                "msg": f"代码生成失败: {str(e)}",
                "data": None
            }
        )


@router.get("/completion", response_model=Dict[str, Any])
async def get_completion(
    file_id: str,
    line: int,
    column: int,
    context: Optional[str] = None,
    language: str = "python",
    user_id: str = Depends(get_current_user_id)
):
    """获取智能补全建议"""
    try:
        # 这里应该从文件服务获取完整代码内容
        # 暂时使用context参数
        code = context or ""
        
        result = await completion_chain.get_completions(
            code=code,
            line=line,
            column=column,
            language=language
        )
        
        return {
            "code": 200,
            "msg": "成功",
            "data": {
                "suggestions": [
                    {
                        "text": s.text,
                        "label": s.label,
                        "detail": s.detail,
                        "insert_text": s.insert_text,
                        "kind": s.kind,
                        "score": s.score
                    }
                    for s in result.suggestions
                ],
                "context": result.context
            }
        }
    
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail={
                "code": 50001,
                "msg": f"智能补全失败: {str(e)}",
                "data": None
            }
        )


@router.post("/analyze", response_model=Dict[str, Any])
async def analyze_code(
    request: AnalysisRequest,
    user_id: str = Depends(get_current_user_id)
):
    """@引用代码分析"""
    try:
        # 解析@引用范围
        scope_parts = request.scope.replace('@', '').split('/')
        
        # 这里应该根据scope获取相关代码文件
        # 暂时使用示例代码
        sample_code = """
def login_user(username, password):
    query = "SELECT * FROM users WHERE username = '" + username + "'"
    # 这里存在SQL注入风险
    return query
"""
        
        result = await code_analysis_chain.analyze_code(
            code=sample_code,
            file_path=request.scope,
            analysis_type="comprehensive"
        )
        
        return {
            "code": 200,
            "msg": "成功",
            "data": {
                "issues": [
                    {
                        "file_path": issue.file_path,
                        "line": issue.line,
                        "column": issue.column,
                        "type": issue.type,
                        "severity": issue.severity,
                        "message": issue.message,
                        "suggestion": issue.suggestion
                    }
                    for issue in result.issues
                ],
                "solution": result.solution,
                "summary": result.summary,
                "score": result.score
            }
        }
    
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail={
                "code": 50001,
                "msg": f"代码分析失败: {str(e)}",
                "data": None
            }
        )


@router.post("/translate", response_model=Dict[str, Any])
async def translate_code(
    request: TranslationRequest,
    user_id: str = Depends(get_current_user_id)
):
    """代码翻译"""
    try:
        # 使用LLM进行代码翻译
        from langchain_core.prompts import ChatPromptTemplate
        from langchain_openai import ChatOpenAI
        from backend.utils.config import get_settings
        
        settings = get_settings()
        # 使用正确的大写属性名
        api_key = settings.OPENAI_API_KEY or "sk-dummy-api-key-for-testing"
        llm = ChatOpenAI(
            model=settings.OPENAI_MODEL,
            temperature=0.1,
            api_key=api_key
        )
        
        translation_prompt = ChatPromptTemplate.from_template("""
        请将以下{source_language}代码翻译为{target_language}代码，
        保持功能逻辑完全一致：
        
        {source_language}代码:
        ```{source_language_lower}
        {code}
        ```
        
        请返回翻译后的{target_language}代码和简要说明。
        """)
        
        chain = translation_prompt | llm
        response = await chain.ainvoke({
            "source_language": request.source_language,
            "target_language": request.target_language,
            "source_language_lower": request.source_language.lower(),
            "code": request.code
        })
        
        # 提取翻译后的代码
        import re
        code_pattern = r'```[\w]*\n(.*?)\n```'
        matches = re.findall(code_pattern, response.content, re.DOTALL)
        translated_code = matches[0].strip() if matches else response.content
        
        return {
            "code": 200,
            "msg": "成功",
            "data": {
                "translated_code": translated_code,
                "explanation": f"已将{request.source_language}代码翻译为{request.target_language}"
            }
        }
    
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail={
                "code": 50001,
                "msg": f"代码翻译失败: {str(e)}",
                "data": None
            }
        )


@router.post("/check/syntax", response_model=Dict[str, Any])
async def check_syntax(
    request: SyntaxCheckRequest,
    user_id: str = Depends(get_current_user_id)
):
    """语法检查"""
    try:
        result = await code_analysis_chain.analyze_code(
            code=request.code,
            file_path="temp_file",
            analysis_type="syntax"
        )
        
        return {
            "code": 200,
            "msg": "成功",
            "data": {
                "errors": [
                    {
                        "line": issue.line,
                        "column": issue.column,
                        "message": issue.message,
                        "severity": issue.severity,
                        "suggestion": issue.suggestion
                    }
                    for issue in result.issues
                ],
                "score": result.score,
                "summary": result.summary
            }
        }
    
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail={
                "code": 50001,
                "msg": f"语法检查失败: {str(e)}",
                "data": None
            }
        )


@router.post("/format", response_model=Dict[str, Any])
async def format_code(
    code: str,
    language: str = "python",
    user_id: str = Depends(get_current_user_id)
):
    """代码格式化"""
    try:
        formatted_code = code
        
        if language.lower() == "python":
            try:
                import black
                formatted_code = black.format_str(code, mode=black.FileMode())
            except Exception as e:
                # 如果格式化失败，返回原代码
                formatted_code = code
        
        return {
            "code": 200,
            "msg": "成功",
            "data": {
                "formatted_code": formatted_code,
                "language": language
            }
        }
    
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail={
                "code": 50001,
                "msg": f"代码格式化失败: {str(e)}",
                "data": None
            }
        )


@router.post("/comment/generate", response_model=Dict[str, Any])
async def generate_comment(
    code: str,
    language: str = "python",
    style: str = "detailed",
    user_id: str = Depends(get_current_user_id)
):
    """生成代码注释"""
    try:
        from langchain_core.prompts import ChatPromptTemplate
        from langchain_openai import ChatOpenAI
        from backend.utils.config import get_settings
        
        settings = get_settings()
        # 使用正确的大写属性名
        api_key = settings.OPENAI_API_KEY or "sk-dummy-api-key-for-testing"
        llm = ChatOpenAI(
            model=settings.OPENAI_MODEL,
            temperature=0.1,
            api_key=api_key
        )
        
        comment_prompt = ChatPromptTemplate.from_template("""
        请为以下{language}代码生成{style_desc}注释：
        
        ```{language_lower}
        {code}
        ```
        
        注释要求：
        1. 符合{language}注释规范
        2. 说明函数/类的功能、参数、返回值
        3. {style_requirements}
        
        只返回注释内容，不要返回代码。
        """)
        
        style_desc = "详细" if style == "detailed" else "简洁"
        style_requirements = (
            "包含参数类型说明、使用示例、注意事项" 
            if style == "detailed" 
            else "简要说明主要功能即可"
        )
        
        chain = comment_prompt | llm
        response = await chain.ainvoke({
            "language": language,
            "language_lower": language.lower(),
            "code": code,
            "style_desc": style_desc,
            "style_requirements": style_requirements
        })
        
        return {
            "code": 200,
            "msg": "成功",
            "data": {
                "comment": response.content.strip(),
                "style": style,
                "language": language
            }
        }
    
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail={
                "code": 50001,
                "msg": f"注释生成失败: {str(e)}",
                "data": None
            }
        )       
